﻿(function () {
    "use strict";
    var groupIdx = 1; // group0 is reserved for MoreItem
    var urlIdx = 0;
    var galleryIdx = 0;
    var pageIdx = 0;
    var curGroupPageIdx = 0;
    var imgGroupList = new WinJS.Binding.List();

    var sortedImgGroupPages = imgGroupList.createGrouped(
        function groupKeySelector(item) { return item.group.order + ""; },
        function groupDataSelector(item) { return item.group; },
        function compareGroups(a, b) { return a - b; }
    );

    var sortedImgGroupPagesList = imgGroupList.createSorted(function (a, b) {
        return a.order - b.order;
    });

    var list = new WinJS.Binding.List();
    var groupedItems = list.createGrouped(
        function groupKeySelector(item) { return item.group.url; },
        function groupDataSelector(item) { return item.group; }
    );

    var galleries = [];
    var urls = [];

    // TODO: Replace the data with your real data.
    // You can add data from asynchronous sources whenever it becomes available.
    //getImgGroupList("http://mm.enterdesk.com/");
    //initializeGallery();
    //loadGalleryAtIndex(0);

    WinJS.Namespace.define("Data", {
        groups: sortedImgGroupPages,
        galleries: galleries,
        getPageList: getPageList,
        getGroupTitle: getGroupTitle,
        getGalleryIdx: getGalleryIdx,
        loadGalleryAtIndex: loadGalleryAtIndex,
        getItemReference: getItemReference,
        getItemsFromGroup: getItemsFromGroup,
        resolveGroupReference: resolveGroupReference,
        resolveItemReference: resolveItemReference,
        resolveGalleryReference: resolveGalleryReference, 
        PhotoDB: PhotoDB,
        initializeGallery: initializeGallery,
        list: list,
        sortedImgGroupPages: sortedImgGroupPages,
        getMoreImgForGroup: getMoreImgForGroup,
    });
    
    function getPageList() {
        return urls;
    }

    function getGalleryIdx() {
        return galleryIdx;
    }

    function getGroupTitle(pageURL) {
        for (var i = 0; i < imgGroupList.length; i++) {
            var item = imgGroupList.getAt(i);
            if (item.url === pageURL) {
                return item.title;
            }
        }
    }

    // Get a reference for an item, using the group key and item title as a
    // unique reference to the item that can be easily serialized.
    function getItemReference(item) {
        return [item.key, item.description];
    }

    // This function returns a WinJS.Binding.List containing only the items
    // that belong to the provided group.
    function getItemsFromGroup(pageURL) {
        return list.createFiltered(function (item) { return item.group.url === pageURL; });
    }

    // Get the unique group corresponding to the provided group key.
    function resolveGroupReference(curPageURL, callBack) {
        if (groupedItems.groups.getItemFromKey(curPageURL) == null) {
            // Do not find the requested group. Load it from online
            getImgForGroup(curPageURL, callBack, galleryIdx);
        }
        else {
            if (callBack) {
                callBack();
            }
        }

        return groupedItems.groups.getItemFromKey(curPageURL);
    }        

    // Get a unique item from the provided string array, which should contain a
    // group key and an item title.
    function resolveItemReference(reference) {
        for (var i = 0; i < groupedItems.length; i++) {
            var item = groupedItems.getAt(i);
            if (item.group.key === reference[0] && item.title === reference[1]) {
                return item;
            }
        }
    }

    function resolveGalleryReference(reference) {
        for (var i = 0; i < galleries.length; i++) {
            var item = galleries[i];
            if (item.name === reference.name) {
                return i;
            }
        }
    }

    function clearCurrentGallery() {
        urlIdx = 0;
        groupIdx = 1;
        urls = [];
        while (imgGroupList.length > 0) {
            imgGroupList.pop();
        }

        while (list.length > 0) {
            list.pop();
        }
        //imgGroupList = new WinJS.Binding.List();
        //list = new WinJS.Binding.List();
        //groupedItems = list.createGrouped(
        //    function groupKeySelector(item) { return item.key; },
        //    function groupDataSelector(item) { return item.group; }
        //);        
    }
    
    function loadGalleryAtIndex(idx, options) {
        if (idx < galleries.length) {
            clearCurrentGallery();
            galleryIdx = idx;

            if (options && options.startPageIdx) {
                urlIdx = options.startPageIdx;
            }

            populateUrls(galleryIdx, options);
            //galleries[idx].getImgGroupList();


            imgGroupList.notifyReload();
            list.notifyReload();
            groupedItems.notifyReload();
        }
    }
    
    function populateUrls(galleryIdx, options) {
        var pages = [];
        var txn = PhotoDB.db.transaction(["Gallery"], "readwrite");
        var request = txn.objectStore("Gallery").get(galleries[galleryIdx].name);

        request.onsuccess = function (evt) {
            var gallery = evt.target.result;
            if (!gallery) {
                return;
            }

            if (gallery.pageGroup) {
                urls = gallery.pageGroup;
            }
            else {
                galleries[galleryIdx].urlParser(options);
                gallery.pageGroup = urls;
                txn.objectStore("Gallery").put(gallery);
            }
        };

        txn.onerror = function (event) {
            WinJS.log && WinJS.log("Unabled to pupulate gallery urls", "PhotoDB", "error")
        }

        txn.oncomplete = function () {
            getImgGroupList(galleryIdx);
        }
    }

    function getImgGroupList(galleryIdx) {
        var txn = PhotoDB.db.transaction(["Page"], "readwrite");
        var index = txn.objectStore("Page").index("groupURL");
        var pageCursor = index.openCursor();
        var checkUpdatePromiseArray = [];
        var today = new Date();

        pageCursor.onsuccess = function (evt) {
            var cursor = evt.target.result;
            if (cursor) {
                var page = cursor.value;
                for (var idx = 0; idx < urls.length; ++idx) {
                    if (urls[idx].url == page.group.url && urls[idx].name == page.group.name) {
                        var urlItem = urls[idx];
                        if (urlItem.lastUpdateTime && urlItem.lastUpdateTime != today.toDateString()) {
                            urlItem.lastUpdateTime = today.toDateString();
                            var checkUpdatePromise = WinJS.xhr({ url: urls[idx].url }).then(function (result) {
                                var newResult = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
                                if (urlItem.oldResult == newResult) {
                                    imgGroupList.push(page);
                                }
                                else {
                                    urlItem.result = newResult;
                                    PhotoDB.updateUrl(galleries[galleryIdx].name, urlItem);
                                    galleries[galleryIdx].groupParser(urlItem);
                                }
                            });
                        }
                        else {
                            imgGroupList.push(page);
                        }

                        checkUpdatePromiseArray.push(checkUpdatePromise);
                    }
                }
                cursor.continue();
            }
            else {
                //WinJS.Promise.join(checkUpdatePromiseArray).done(function () {
                    if (galleries[galleryIdx].type == "website") {
                        for (var urlIdx = 0; urlIdx < urls.length; ++urlIdx) {
                            if (urls[urlIdx].result && urls[urlIdx].lastUpdateTime) {
                                continue;
                            }
                            else {
                                if (urls[urlIdx].result) {
                                    galleries[galleryIdx].groupParser(urls[urlIdx]);
                                }
                                else {
                                    (function wrapper(urlItem) {
                                        var feed = WinJS.xhr({ url: urls[urlIdx].url });

                                        feed.then(function (result) {
                                            urlItem.result = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
                                            urlItem.lastUpdateTime = today.toDateString();
                                            PhotoDB.updateUrl(galleries[galleryIdx].name, urlItem);
                                            galleries[galleryIdx].groupParser(urlItem);
                                        });
                                    })(urls[urlIdx]);
                                }
                            }

                            
                        }
                    }
                    else if (galleries[galleryIdx].type == "local" || galleries[galleryIdx].type == "search") {
                        galleries[galleryIdx].groupParser(urls[0]);
                    }
                //});
            }
        };
    }

    function getImgForGroup(pageURL, callBack, galleryIdx) {
        var groupItem = null;

        curGroupPageIdx = 0;

        for (var i = 0; i < imgGroupList.length; i++) {
            var ttt = imgGroupList.getAt(i);
            if (imgGroupList.getAt(i).url == pageURL) {
                groupItem = imgGroupList.getAt(i);
                break;
            }
        }

        if (groupItem == null) {
            callBack();
            return;
        }

        var txn = PhotoDB.db.transaction(["Image"], "readwrite");
        var index = txn.objectStore("Image").index("pageURL");
        var imageCursor = index.openCursor();
        var isCached = false;
        imageCursor.onsuccess = function (evt) {
            var cursor = evt.target.result;
            if (cursor) {
                var image = cursor.value;
                if (image.pageURL == pageURL) {
                    isCached = true;
                    list.push({
                        caption: image.name,                        
                        backgroundImage: image.backgroundImage,
                        url: image.url,                        
                        width: image.width,
                        height: image.height,
                        group: groupItem,
                    });
                }
                cursor.continue();
            }
            else if (!isCached) {
                if (galleries[galleryIdx].type == "website") {
                    var feed = WinJS.xhr({ url: groupItem.url.replace(/#\d*/, "") });
                    feed.then(function (result) {
                        galleries[galleryIdx].imgParser(result, pageURL, groupItem);
                    }).done(callBack);
                }
                else if (galleries[galleryIdx].type == "local" || galleries[galleryIdx].type == "search") {
                    galleries[galleryIdx].imgParser(pageURL, groupItem, callBack);
                }
            }
        }

        txn.oncomplete = function () {
            if (isCached) {
                callBack();
            }
        }
    }

    function getMoreImgForGroup(curPageURL, callBack) {
        if (galleries[galleryIdx].getMoreImgForGroup) {
            galleries[galleryIdx].getMoreImgForGroup(curPageURL, callBack);
        }
    }
    //////////////////////////////////////////////////
    // Local
    /////////////////////////////////////////////////

    function urlParserLocal() {
        urls.push({
            name: "local",
            url: "local",
            order: 0,
        });
        
    }

    function getSubFoldersRecursive(folder, group) {
        var group = group;
        var fileTypeFilter = [".jpg", ".png", ".bmp", ".gif"];
        var queryOptions = new Windows.Storage.Search.QueryOptions(Windows.Storage.Search.CommonFileQuery.orderByName, fileTypeFilter);
        queryOptions.folderDepth = Windows.Storage.Search.FolderDepth.shallow;
        queryOptions.indexerOption = Windows.Storage.Search.IndexerOption.useIndexerWhenAvailable;

        var fileQuery = folder.createFileQueryWithOptions(queryOptions).getFilesAsync().done(function (files) {
            if (files.size > 0) {
                folder.getThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.picturesView).done(function (thumb) {
                    imgGroupList.push({
                        title: folder.name,
                        backgroundImage: thumb ? URL.createObjectURL(thumb) : "",
                        url: folder.path,
                        group: { name: "local", url: "local" },
                        subtitle: folder.path,
                    });

                    folder.getBasicPropertiesAsync().done(function (prop) {
                        PhotoDB.updatePage({
                            name: folder.name,
                            description: folder.path,
                            pageURL: folder.path,
                            backgroundImage: thumb ? URL.createObjectURL(thumb, { oneTimeOnly: true }) : "",
                            group: { name: "local", url: "local" },
                            timestamp: prop.dateModified.toString(),
                        });
                    });
                });
            }
        });

        var folderQuery = folder.createFolderQuery();
        folderQuery.getFoldersAsync().done(function (folders) {
            var properties = Windows.Storage.FileProperties.ThumbnailMode;
            folders.forEach(function (folder) {
                getSubFoldersRecursive(folder, group);
            });
        });
    }

    function groupParserLocal(group) {
        var picturesLibrary = Windows.Storage.KnownFolders.picturesLibrary;        
        getSubFoldersRecursive(picturesLibrary, group);
    }

    function imgParserLocal(pageURL, groupItem, callBack) {
        var fileTypeFilter = [".jpg", ".png", ".bmp", ".gif"];
        var queryOptions = new Windows.Storage.Search.QueryOptions(Windows.Storage.Search.CommonFileQuery.orderByName, fileTypeFilter);        
        queryOptions.folderDepth = Windows.Storage.Search.FolderDepth.shallow;
        queryOptions.indexerOption = Windows.Storage.Search.IndexerOption.useIndexerWhenAvailable;

        var curFolder;
        if (pageURL === "") {
            curFolder = new WinJS.Promise(function (completed) {
                completed(Windows.Storage.KnownFolders.picturesLibrary);
            });
        }
        else {
            curFolder = Windows.Storage.StorageFolder.getFolderFromPathAsync(pageURL);
        }

        curFolder.done(function (folder) {
            var fileQuery = folder.createFileQueryWithOptions(queryOptions);
            var delayLoad = true;
            var access = new Windows.Storage.BulkAccess.FileInformationFactory(
                                fileQuery, Windows.Storage.FileProperties.ThumbnailMode.picturesView,
                                1026,
                                Windows.Storage.FileProperties.ThumbnailOptions.returnOnlyIfCached,
                                delayLoad);

            access.getFilesAsync().then(function (files) {
                files.forEach(function (file) {
                    list.push({
                        caption: file.name,
                        backgroundImage: URL.createObjectURL(file, { oneTimeOnly: true }),
                        url: URL.createObjectURL(file, { oneTimeOnly: true }),
                        width: file.imageProperties.width,
                        height: file.imageProperties.width,
                    });
                });
            }).done(callBack);            
        });
    }

    //////////////////////////////////////////////////
    // PHD Comic
    /////////////////////////////////////////////////

    function urlParserPhd() {
        var year = 1997;
        for (; year <= 2012; ++year) {
            urls.push({
                name: year + "",
                url: "http://www.phdcomics.com/comics/archive_list.php",
                order: -year,
                result: null,
                lastUpdateTime: null,
            });
        }
    }

    function groupParserPhd(urlItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = urlItem.result;
        var imgNodes = doc.querySelectorAll("img");
        var groupImgUrlPrefix = "http://www.phdcomics.com/comics/images/";
        var groupOrder = 0;
        var quaterYear = "";
        var quater = "";
        var year = "";
        var regStr = new RegExp("(spring|summer|fall|winter)" + urlItem.name + ".gif");

        for (var idx = 0; idx < imgNodes.length; ++idx) {
            var imgUrl = imgNodes[idx].getAttribute("src");
            var result = regStr.exec(imgUrl);
            if (imgUrl && regStr.exec(imgUrl) != null) {
                quaterYear = imgUrl.replace(groupImgUrlPrefix, "").replace(".gif", "");
                quater = quaterYear.substring(0, quaterYear.length - 4);
                year = quaterYear.substring(quaterYear.length - 4, quaterYear.lenght);
                groupOrder = parseInt(year) * 10 + (quater == "spring") * 0 + (quater == "summer") * 1 + (quater == "fall") * 2 + (quater == "winter") * 3;

                var newImgGroup = {
                    title: imgUrl.replace(groupImgUrlPrefix, "").replace(".gif", ""),
                    backgroundImage: imgUrl,
                    url: "http://www.phdcomics.com/comics/archive_list.php#" + imgGroupList.length,
                    subtitle: "",
                    group: urlItem,
                    order: groupOrder,
                };

                imgGroupList.push(newImgGroup);
                PhotoDB.updatePage(newImgGroup);
            }
        }
    }

    function imgParserPhd(result, pageURL, groupItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));

        //var yearTableGroups = doc.querySelector("body > table").querySelector("tbody").children[1].querySelectorAll("td>div>table");
        var imgNode = doc.querySelector("img[src = \"" + groupItem.backgroundImage + "\"");
        var tableNode = imgNode.parentNode.parentNode.parentNode;
        var contentNodeGroup = tableNode.children[1];

        var yearIdx = 0;
        for (; yearIdx < tableNode.children[0].children.length; ++yearIdx) {
            if (tableNode.children[0].children[yearIdx].querySelector("img[src = \"" + groupItem.backgroundImage + "\"") != null) {
                break;
            }
        }

        var contentNodes = contentNodeGroup.children[yearIdx].querySelectorAll("tr");
        for (var contentIdx = 0; contentIdx < contentNodes.length; ++contentIdx) {
            var link = contentNodes[contentIdx].children[1].querySelector("a").getAttribute("href");
            var title = contentNodes[contentIdx].children[2].querySelector("font").innerText;
            var doc = document.implementation.createHTMLDocument('');

            var request = new XMLHttpRequest();
            request.open("GET", link, false);
            request.send();
            doc.documentElement.innerHTML = toStaticHTML(request.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
            var contentImgNodes = doc.querySelectorAll("img");
            for (var imgIdx = 0; imgIdx < contentImgNodes.length; ++imgIdx) {
                if (contentImgNodes[imgIdx].getAttribute("src").search("/archive/") != -1) {
                    list.push({
                        caption: title,
                        backgroundImage: contentImgNodes[imgIdx].getAttribute("src"),
                        url: contentImgNodes[imgIdx].getAttribute("src"),
                        width: 0,
                        height: 0,
                        pageURL: pageURL,
                        group: groupItem
                    });

                    PhotoDB.updateImage({
                        caption: title,
                        backgroundImage: contentImgNodes[imgIdx].getAttribute("src"),
                        url: contentImgNodes[imgIdx].getAttribute("src"),
                        width: 0,
                        height: 0,
                        pageURL: pageURL,
                        group: groupItem
                    });
                }
            }
        }
    }

    //////////////////////////////////////////////////
    // Garfield Comic
    /////////////////////////////////////////////////

    function urlParserGarfield() {
        var request = new XMLHttpRequest();
        request.open("GET", "http://pt.jikos.cz/garfield", false);
        request.send();

        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = toStaticHTML(request.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
        var yearNodes = doc.querySelectorAll("p > a");
        if (yearNodes && yearNodes.length > 0) {            
            for (var idx = 0; idx < yearNodes.length; ++idx) {
                if (yearNodes[idx].getAttribute("href") && yearNodes[idx].getAttribute("href").indexOf("garfield") != -1) {
                    urls.push({
                        name: yearNodes[idx].innerText,
                        url: "http://pt.jikos.cz" + yearNodes[idx].getAttribute("href"),
                        order: -idx,
                    });
                }
            }
        }
    }

    function groupParserGarfield(urlItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = urlItem.result;
        var backgroundImage = doc.querySelector("img").getAttribute("src");

        var newImgGroup = {
            title: urlItem.name,
            backgroundImage: backgroundImage,
            url: urlItem.url,
            subtitle: "",
            group: urlItem,
            order: urlItem.order,
        };

        imgGroupList.push(newImgGroup);
        PhotoDB.updatePage(newImgGroup);
    }

    function imgParserGarfield(result, pageURL, groupItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));

        //var yearTableGroups = doc.querySelector("body > table").querySelector("tbody").children[1].querySelectorAll("td>div>table");
        var title = groupItem.title;
        var imgNode = doc.querySelectorAll("table img");
        for (var idx = 0; idx < imgNode.length; ++idx) {
            var src = imgNode[idx].getAttribute("src");
            var caption = imgNode[idx].getAttribute("alt");
            if (caption.search("garfield") != -1) {
                list.push({
                    caption: caption,
                    backgroundImage: src,
                    url: src,
                    width: 0,
                    height: 0,
                    pageURL: pageURL,
                    group: groupItem
                });

                PhotoDB.updateImage({
                    caption: caption,
                    backgroundImage: src,
                    url: src,
                    width: 0,
                    height: 0,
                    pageURL: pageURL,
                    group: groupItem
                });
            }
        }
    }

    function getMoreImgForGroupGarfield(groupUrl, callBack) {
        var feed = WinJS.xhr({ url: groupUrl });
        feed.then(function (result) {
            var doc = document.implementation.createHTMLDocument('');
            doc.documentElement.innerHTML = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
            var monthNodes = doc.querySelectorAll("p")[1].children;
            var curMonthNode = null;

            if (curGroupPageIdx < monthNodes.length) {
                curMonthNode = monthNodes[curGroupPageIdx++];
            }
            else {
                return;
            }
            
            var ttt = "http://pt.jikos.cz" + curMonthNode.getAttribute("href");
            var feed2 = WinJS.xhr({ url: "http://pt.jikos.cz" + curMonthNode.getAttribute("href") });
            feed2.then(function (result) {
                var group = groupedItems.groups.getItemFromKey(groupUrl);
                imgParserGarfield(result, groupUrl, group.data)
            }).done(callBack);
        });
    }

    //////////////////////////////////////////////////
    // Boston
    /////////////////////////////////////////////////

    function urlParserBoston() {
        var request = new XMLHttpRequest();
        request.open("GET", "http://www.boston.com/bigpicture/", false);
        request.send();

        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = toStaticHTML(request.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
        if (doc.getElementsByClassName("drp").length > 0) {
            var urlNodes = doc.getElementsByClassName("drp")[0].getElementsByTagName("option");
            for (var idx = 0; idx < urlNodes.length; ++idx) {
                if (urlNodes[idx].attributes.getNamedItem("value")) {
                    urls.push({
                        name: urlNodes[idx].innerText,
                        url: urlNodes[idx].getAttribute("value"),
                        order: idx,
                    });
                }
            }
        }
    }

    function groupParserBoston(urlItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = urlItem.result;
        var itemNodes = doc.querySelectorAll("td");
        var groupOrder = 0

        for (var idx = 0; idx < itemNodes.length; ++idx) {
            var titleNode = itemNodes[idx].querySelector("a");
            var imgNode = itemNodes[idx].querySelector("img");
            if (titleNode && imgNode) {
                var newImgGroup = {
                    title: titleNode.innerText,
                    backgroundImage: imgNode.getAttribute("src"),
                    url: titleNode.getAttribute("href"),
                    subtitle: "",
                    group: group,
                    order: group.order * 100 + groupOrder,
                };

                imgGroupList.push(newImgGroup);
                PhotoDB.updatePage(newImgGroup);

                groupOrder++;
            }
        }
    }

    function imgParserBoston(result, pageURL, groupItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
        var imgNodes = doc.getElementsByClassName("bpImage");
        var captionNodes = doc.getElementsByClassName("bpCaption");

        for (var idx = 0; idx < imgNodes.length && idx < captionNodes.length; ++idx) {
            list.push({
                caption: captionNodes[idx].innerText,
                backgroundImage: imgNodes[idx].attributes.getNamedItem("src").nodeValue,
                url: imgNodes[idx].attributes.getNamedItem("src").nodeValue,
                width: parseInt(imgNodes[idx].style.width),
                height: parseInt(imgNodes[idx].style.height),
                pageURL: pageURL,
                group: groupItem
            });

            PhotoDB.updateImage({
                caption: captionNodes[idx].innerText,
                backgroundImage: imgNodes[idx].attributes.getNamedItem("src").nodeValue,
                url: imgNodes[idx].attributes.getNamedItem("src").nodeValue,
                width: parseInt(imgNodes[idx].style.width),
                height: parseInt(imgNodes[idx].style.height),
                pageURL: pageURL,
                group: groupItem
            });
        }
    }

    //////////////////////////////////////////////////
    // Girl
    /////////////////////////////////////////////////

    function urlParserGirl() {
        urls.push({ name: "Page 1", url: "http://mm.enterdesk.com/" });
        for (var idx = 2; idx <= 20; ++idx) {
            urls.push({
                name: "Page " + idx,
                url: "http://mm.enterdesk.com/" + idx + ".html",
                order: idx,
            });
        }
    }
    
    function groupParserGirl(urlItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = urlItem.result;
        var itemNodes = doc.querySelectorAll(".ny dd");
        var groupOrder = 0;

        for (var idx = 0; idx < itemNodes.length; ++idx) {
            var imgNode = itemNodes[idx].querySelector("img");
            if (imgNode) {
                var newImgGroup = {
                    title: imgNode.getAttribute("title"),
                    backgroundImage: imgNode.getAttribute("src"),
                    url: imgNode.parentNode.getAttribute("href"),
                    subtitle: null,
                    group: urlItem,
                    order: group.order * 100 + groupOrder,
                };

                imgGroupList.push(newImgGroup);
                PhotoDB.updatePage(newImgGroup);

                groupOrder++;
            }
        }
    }

    function imgParserGirl(result, pageURL, groupItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
        var imgNodes = doc.querySelectorAll(".npicdlm");

        for (var idx = 0; idx < imgNodes.length; ++idx) {
            list.push({
                caption: imgNodes[idx].querySelector("dt a").innerText,
                backgroundImage: imgNodes[idx].querySelector("img").getAttribute("src").replace("200.150.jpg", "700.525.jpg"),
                url: imgNodes[idx].querySelector("img").getAttribute("src").replace("200.150.jpg", "700.525.jpg"),
                width: 0,
                height: 0,
                pageURL: pageURL,
                group: groupItem
            });

            PhotoDB.updateImage({
                caption: imgNodes[idx].querySelector("dt a").innerText,
                backgroundImage: imgNodes[idx].querySelector("img").getAttribute("src").replace("200.150.jpg", "700.525.jpg"),
                url: imgNodes[idx].querySelector("img").getAttribute("src").replace("200.150.jpg", "700.525.jpg"),
                width: 0,
                height: 0,
                pageURL: pageURL,
                group: groupItem
            });
        }
    }

    //////////////////////////////////////////////////
    // JJGirl
    /////////////////////////////////////////////////

    function urlParserJJGirls() {
        var letters = "abcdefghijklmnopqrstuvwxyz";
        for (var letterIdx = 0; letterIdx < letters.length; ++letterIdx) {
            urls.push({
                name: "Page " + letters[letterIdx],
                url: "http://www.jjgirls.com/models/" + letters[letterIdx],
                order: letterIdx,
            });
        }
    }

    function groupParserJJGirls(urlItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = urlItem.result;
        var itemNodes = doc.querySelectorAll('.p160222 > a');
        var groupOrder = 0;

        for (var idx = 0; idx < itemNodes.length; ++idx) {
            var imgNode = itemNodes[idx].querySelector("img");
            if (imgNode && imgNode.parentNode.getAttribute("href").indexOf("gallery") != -1) {
                var newImgGroup = {
                    title: imgNode.parentNode.innerText,
                    backgroundImage: imgNode.getAttribute("src"),
                    url: "http://" + imgNode.parentNode.getAttribute("href").replace(/(.|\s)*?http%3a\/\//, "").replace(/\/\d+\/$/, "/1/"),
                    subtitle: null,
                    group: urlItem,
                    order: urlItem.order * 100 + groupOrder,
                };

                imgGroupList.push(newImgGroup);
                PhotoDB.updatePage(newImgGroup);

                groupOrder++;
            }
        }
    }

    function imgParserJJGirl(result, pageURL, groupItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
        var imgPages = doc.querySelectorAll(".matchlinks a");

        var lastPageNum = 1;
        var pagePrefix = groupItem.url.replace(/\/(\d+)\/$/, "");
        if (imgPages.length > 0) {
            lastPageNum = parseInt(imgPages[imgPages.length - 1].getAttribute("href").match(/\/(\d+)\/$/)[1]);
            pagePrefix = "http://www.jjgirls.com" + imgPages[imgPages.length - 1].getAttribute("href").replace(/\/(\d+)\/$/, "");
        }
        else {
            loadSubPageJJGirls(groupItem.url, pageURL, groupItem);
        }

        for (pageIdx = 1; pageIdx < lastPageNum; ++pageIdx) {
            loadSubPageJJGirls(pagePrefix + "/" + pageIdx, pageURL, groupItem)
        }
    }

    function loadSubPageJJGirls(url, pageURL, groupItem) {
        var feed2 = WinJS.xhr({ url: url });
        feed2.then(function (result) {
            var doc2 = document.implementation.createHTMLDocument('');
            doc2.documentElement.innerHTML = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
            var imgs = doc2.querySelectorAll(".p160222 a");
            for (var imgIdx = 0; imgIdx < imgs.length; ++imgIdx) {
                if (imgs[imgIdx].getAttribute("href").indexOf("http") != -1) {
                    list.push({
                        caption: "",
                        backgroundImage: imgs[imgIdx].getAttribute("href"),
                        url: imgs[imgIdx].getAttribute("href"),
                        pageURL: pageURL,
                        group: groupItem
                    });

                    PhotoDB.updateImage({
                        caption: "",
                        backgroundImage: imgs[imgIdx].getAttribute("href"),
                        url: imgs[imgIdx].getAttribute("href"),
                        width: 0,
                        height: 0,
                        pageURL: pageURL,
                        group: groupItem
                    });
                }
            }
        });
    }

    //////////////////////////////////////////////////
    // Dark
    /////////////////////////////////////////////////

    function urlParserDark() {
        for (var idx = 0; idx <= 23; ++idx) {
            urls.push({
                name: "Page " + idx,
                url: "http://www.bobx.com/av-idol/av-idols_sorted_by_age.html?page=" + idx + ".html",
                order: idx,
            });
        }
    }

    function groupParserDark(urlItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = urlItem.result;
        var itemNodes = doc.querySelectorAll('.smallred');
        var groupOrder = 0;

        var moreItem = imgGroupList.pop();

        for (var idx = 0; idx < itemNodes.length; ++idx) {
            var imgNode = itemNodes[idx].querySelector("img");
            if (imgNode) {
                var newImgGroup = {
                    title: itemNodes[idx].getAttribute("title"),
                    backgroundImage: imgNode.getAttribute("src"),
                    url: "http://www.bobx.com" + itemNodes[idx].getAttribute("href"),
                    subtitle: null,
                    group: urlItem,
                    order: urlItem.order * 100 + groupOrder,
                };

                imgGroupList.push(newImgGroup);
                PhotoDB.updatePage(newImgGroup);

                groupOrder++;
            }
        }
    }

    function imgParserDark(result, pageURL, groupItem) {
        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = toStaticHTML(result.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
        var imgPages = doc.querySelectorAll(".whitesmall .smallblack");

        for (var pageIdx = 0; pageIdx < imgPages.length; ++pageIdx) {
            var imgPage = "http://www.bobx.com" + imgPages[pageIdx].getAttribute("href");
            var request = new XMLHttpRequest();
            request.open("GET", imgPage, false);
            request.send();
            doc = document.implementation.createHTMLDocument('');
            doc.documentElement.innerHTML = toStaticHTML(request.responseText.replace(/<script(.|\s)*?\/script>/g, ''));

            var imgs = doc.querySelectorAll("td img");
            for (var imgIdx = 0; imgIdx < imgs.length; ++imgIdx) {
                if (imgs[imgIdx].getAttribute("src").indexOf("preview") != -1) {
                    list.push({
                        caption: "",
                        backgroundImage: "http://www.bobx.com" + imgs[imgIdx].getAttribute("src").replace("preview-", "").replace("\/thumbnail", ""),
                        url: "http://www.bobx.com" + imgs[imgIdx].getAttribute("src").replace("preview-", "").replace("\/thumbnail", ""),
                        pageURL: pageURL,
                        group: groupItem
                    });

                    PhotoDB.updateImage({
                        caption: "",
                        backgroundImage: "http://www.bobx.com" + imgs[imgIdx].getAttribute("src").replace("preview-", "").replace("\/thumbnail", ""),
                        url: "http://www.bobx.com" + imgs[imgIdx].getAttribute("src").replace("preview-", "").replace("\/thumbnail", ""),
                        width: 0,
                        height: 0,
                        pageURL: pageURL,
                        group: groupItem
                    });
                }
            }
        }
    }

    //////////////////////////////////////////////////
    // Bing Search
    /////////////////////////////////////////////////

    function urlParserBing(options) {
        urls.push({
            name: "Bing",
            url: "https://api.datamarket.azure.com/Bing/Search/Image?$format=json&Adult=%27off%27&Query=%27" + encodeURIComponent(options.keyword) + "%27",
            order: 0,
        });
    }

    function groupParserBing(group) {
        imgGroupList.push({
            key: "group" + pageIdx,
            title: "Powered by Bing Search",
            backgroundImage: "http://popsop.com/wp-content/uploads/bing_logo.jpg",
            url: group.url,
            subtitle: "Results: " + pageIdx * 50 + " - " + (pageIdx + 1) * 50,
            group: group,
            order: pageIdx,
        });

        //for (var pageIdx = 0; pageIdx < 10; ++pageIdx) {
        //    imgGroupList.push({
        //        key: "group" + pageIdx,
        //        title: "Powered by Bing Search",
        //        backgroundImage: "http://popsop.com/wp-content/uploads/bing_logo.jpg",
        //        url: group.url + "&$skip=" + pageIdx * 50,
        //        subtitle: "Results: " + pageIdx * 50 + " - " + (pageIdx + 1) * 50,
        //        group: group,
        //        order: pageIdx,
        //    });
        //}
    }

    function imgParserBing(pageURL, groupItem, callBack) {
        var accountKey = "psssxRZvnKno3XVu1L2o022G7Tkp5oTIknONeKwFHew= ";

        var feed = WinJS.xhr({
            url: pageURL,
            user: accountKey,
            password: accountKey
        });

        feed.then(function (result) {
            var jsonList = jQuery.parseJSON(result.responseText);
            for (var idx = 0; idx < jsonList.d.results.length; ++idx) {
                list.push({
                    caption: jsonList.d.results[idx].Title,
                    backgroundImage: jsonList.d.results[idx].Thumbnail.MediaUrl,
                    url: jsonList.d.results[idx].MediaUrl,
                    width: jsonList.d.results[idx].Width,
                    height: jsonList.d.results[idx].Height,
                    pageURL: pageURL,
                    group: groupItem
                });
            }
        }).done(callBack);
    }

    function getMoreImgForGroupBing(groupUrl, callBack) {        
        var group = groupedItems.groups.getItemFromKey(groupUrl);
        var nextURL = groupUrl + "&$skip=" + group.groupSize;
        imgParserBing(nextURL, group.data, callBack);
    }

    //////////////////////////////////////////////////
    // Others
    /////////////////////////////////////////////////

    function populateUrls4() {
        $.ajaxSetup({ async: false });
        urls.push("http://www.1kkk.com/manhua-list/");
        $.get(urls[0], {}, function (data) {
            data = toStaticHTML(data.replace(/<script(.|\s)*?\/script>/g, ''));
            var allLinks = $("#search_fy a", data);
            if (allLinks && allLinks.length >= 2) {
                var lastPage = parseInt(allLinks[allLinks.length - 2].innerText);
                for (var newPageIdx = 2; newPageIdx <= lastPage; ++newPageIdx) {
                    urls.push("http://www.1kkk.com/manhua-new-p" + newPageIdx + "/");
                }
            }
        });
    }
    
    function getImgGroupList4() {
        if (urlIdx >= urls.length) {
            return;
        }
        $.ajaxSetup({ async: true });
        //$.ajaxSetup({ ajaxSettings: { contentType: "application/x-www-form-urlencoded;charset=gbk" } });
        $.get(urls[urlIdx], {}, function (data) {
            var moreItem = imgGroupList.pop();
            data = toStaticHTML(data.replace(/<script(.|\s)*?\/script>/g, ''))
            $(".cover", data).each(function (index, elem) {
                if ($("a_comicname2", elem) && $("a", elem)) {                    
                        imgGroupList.push({
                            key: "group" + (groupIdx++),
                            title: $("a", elem)[0].innerText,
                            backgroundImage: $("img", elem)[0].getAttribute("src"),
                            url: "http://www.1kkk.com" + $("a", elem)[0].getAttribute("href"),
                            subtitle: null,
                        });
                }
            });

            if (moreItem == null) {
                moreItem = {
                    key: "group0",
                    title: "Get More Images ...",
                    backgroundImage: "",
                    url: urls[urlIdx++],
                    subtitle: "",
                };
            }
            else {
                if (urlIdx + 1 < urls.length) {
                    moreItem.url = urls[urlIdx++];
                }
            }

            imgGroupList.push(moreItem);
        });
    }

    function getImgForGroup4(key, callBack) {
        var groupItem = null;

        for (var i = 0; i < imgGroupList.length; i++) {
            if (imgGroupList.getAt(i).key == key) {
                groupItem = imgGroupList.getAt(i);
            }
        }

        if (groupItem == null) {
            return;
        }

        // Build chapter list
        var chapterList = [];
        $.ajaxSetup({ async: false });
        $.get(groupItem.url, {}, function (data) {
            data = toStaticHTML(data.replace(/<script(.|\s)*?\/script>/g, ''));
            if ($(".sy_nr1", data).length > 1) {
                $("li", $(".sy_nr1", data)[1]).each(function (index, item) {
                    if ($("a", item)) {
                        chapterList.push({
                            url: "http://www.1kkk.com" + $("a", item)[0].getAttribute("href"),
                            chapter: $("a", item)[0].innerText,
                        });
                    }
                });
            }
            else {
                $("li", $(".sy_nr1", data)[0]).each(function (index, item) {
                    if ($("a", item)) {
                        chapterList.push({
                            url: "http://www.1kkk.com" + $("a", item)[0].getAttribute("href"),
                            chapter: $("a", item)[0].innerText,
                        });                        
                    }
                });
                chapterList.reverse();
            }
        });

        for (var chapterIdx = 0; chapterIdx < chapterList.length; ++chapterIdx) {
            $.get(chapterList[chapterIdx].url, {}, function (data) {
                
                // Unsafe get dynamic content
                var allLinks = MSApp.execUnsafeLocalFunction(function () {                    
                    var cid = data.match(/var cid=(\d*)/)[1];                                       
                    
                    var mkeyCode = data.match(/(\(function\(p,a,c,k,e,d\)(.|\s)*?)<\/script>/)[1].replace(/\["|d|w]/g, "").replace(/\\/, "");
                    var ttt = $("#dm5_key", data)[1];
                    mkeyCode = "console.log(" + $.trim(mkeyCode) + ")";
                    $.globalEval(mkeyCode);
                    if ($("#dm5_key", data).length > 0) {
                        mkey = $("#dm5_key", data).innerText;
                    }

                    var doc = document.implementation.createHTMLDocument('');
                    doc.documentElement.innerHTML = data;

                    

                    var seddd = $("#cpimg", doc);
                    $.get("http://www.1kkk.com/chapterimagefun.ashx?d=" + new Date(),
                          {cid: cid, 
                              page: 2, 
                              key: 	"",
                              maxcount: 10 
                          },
                          function (data) {
                              var tt = data;
                              var d = null;
                              var tttt = eval(data);
                              
                              var dda = d;
                          }
                    );
                    var doc = document.implementation.createHTMLDocument('');
                    doc.documentElement.innerHTML = data;                    
                    return $("#chapterpager a", doc);
                });

                if (allLinks && allLinks.length >= 1) {
                    var lastPage = parseInt(allLinks[allLinks.length - 1].innerText);
                    var firstPageUrl = $("#cpimg", data).length > 0 ? $("#cpimg", data)[0].getAttribute("src") : null;
                    for (var newPageIdx = 1; newPageIdx <= lastPage; ++newPageIdx) {
                        var str = '' + newPageIdx;
                        while (str.length < 3) {
                            str = '0' + str;
                        }

                        list.push({
                            key: key,
                            group: groupItem,
                            backgroundImage: firstPageUrl.replace("001", str),
                            caption: null,
                        });
                    }
                }
            });
        }

        var request = new XMLHttpRequest();
        request.open("GET", groupItem.url, false);
        request.send();

        var doc = document.implementation.createHTMLDocument('');
        doc.documentElement.innerHTML = toStaticHTML(request.responseText.replace(/<script(.|\s)*?\/script>/g, ''));
        var imgPages = doc.querySelectorAll(".whitesmall .smallblack");

        for (var pageIdx = 0; pageIdx < imgPages.length; ++pageIdx) {
            var imgPage = "http://www.bobx.com" + imgPages[pageIdx].getAttribute("href");
            request = new XMLHttpRequest();
            request.open("GET", imgPage, false);
            request.send();
            doc = document.implementation.createHTMLDocument('');
            doc.documentElement.innerHTML = toStaticHTML(request.responseText.replace(/<script(.|\s)*?\/script>/g, ''));

            var imgs = doc.querySelectorAll("td img");
            for (var imgIdx = 0; imgIdx < imgs.length; ++imgIdx) {
                if (imgs[imgIdx].getAttribute("src").indexOf("preview") != -1) {
                    list.push({
                        key: key,
                        group: groupItem,
                        backgroundImage: "http://www.bobx.com" + imgs[imgIdx].getAttribute("src").replace("preview-", "").replace("\/thumbnail", ""),
                        caption: null,
                    });
                }
            }
        }
    }

    
        
    function initializeGallery() {
        galleries = [
            { name: "Garfield Comic", description: "Garfield Comic", url: "http://pt.jikos.cz/garfield/", urlParser: urlParserGarfield, groupParser: groupParserGarfield, imgParser: imgParserGarfield, getMoreImgForGroup: getMoreImgForGroupGarfield, type: "website" },
            { name: "PhD Comic", description: "PHD Comic", url: "http://www.phdcomics.com/comics/archive_list.php", urlParser: urlParserPhd, groupParser: groupParserPhd, imgParser: imgParserPhd, type: "website" },            
            { name: "Local", description: "Local Photo Library", url: "", urlParser: urlParserLocal, groupParser: groupParserLocal, imgParser: imgParserLocal, type: "local" },
            { name: "Boston", description: "Boston Big Picture", url: "http://www.boston.com/bigpicture/", urlParser: urlParserBoston, groupParser: groupParserBoston, imgParser: imgParserBoston, type: "website" },
            //{ name: "Girl", description: "Girl", url: "http://mm.enterdesk.com/", backgroundImage: "http://www.enterdesk.com/statics/enterdesk/images/logo.jpg", urlParser: urlParserGirl, groupParser: groupParserGirl, imgParser: imgParserGirl, type: "website" },            
            //{ name: "Comic", populateUrls: populateUrls4, getImgGroupList: getImgGroupList4, getImgForGroup: getImgForGroup4, type: "website" },
            //{ name: "Dark", description: "Dark", url: "http://www.bobx.com", backgroundImage: "", urlParser: urlParserDark, groupParser: groupParserDark, imgParser: imgParserDark, type: "website" },
            //{ name: "JJGirls", description: "Japan Girls", url: "http://www.jjgirls.com/models/", backgroundImage: "", urlParser: urlParserJJGirls, groupParser: groupParserJJGirls, imgParser: imgParserJJGirl, type: "website" },            
            { name: "Bing", description: "Bing Search", url: "http://popsop.com/wp-content/uploads/bing_logo.jpg", urlParser: urlParserBing, groupParser: groupParserBing, imgParser: imgParserBing, getMoreImgForGroup: getMoreImgForGroupBing, type: "search" },
            //{ name: "Baidu", populateUrls: populateUrlsBaidu, getImgGroupList: getImgGroupListBaidu, getImgForGroup: getImgForGroupBaidu, type: "search"},            
        ];

        return galleries;
    }
    
})();
